package com.inexas.cu.server.pipe;

import com.google.gwt.event.shared.*;
import com.google.inject.*;
import com.inexas.cu.client.pipe.*;
import com.inexas.cu.server.pipe.ServiceRegistry.*;
import com.inexas.util.*;

@Singleton
public class NullPipe implements PipeClientEnd, RequestHandler<AbstractRequest>, PipeServerEnd {
	private final HandlerManager eventBus;
	private final ServiceRegistry registry;
	private String credentials;
	// todo Split this class so I can put the client end in client
	
	@Inject
	public NullPipe(HandlerManager eventBus) {
		this.eventBus = eventBus;
		this.registry = new ServiceRegistry();
		
		eventBus.addHandler(AbstractRequest.getType(), this);
    }

	/**
	 * Handle server bound traffic passing the response back to the event bus
	 * 
	 * @param event
	 */
	public void onFired(RequestEvent<AbstractRequest> event) {
		final AbstractRequest request = event.getRequest();
		// Test serialization
		assert SerializationUtilities.isSerializable(request) :	//
			"Not serializable. Implement Serializable and a default ctor?: " +	//
			request.getClass().getName();
		request.setRequestId();
		request.setCredentials(credentials);
		final AbstractResponse response = registry.fire(event.getRequest());
		assert SerializationUtilities.isSerializable(response) :	//
			"Not serializable. Implement Serializable and a default ctor?: " +	//
			response.getClass().getName();
		eventBus.fireEvent(new ResponseEvent<AbstractResponse>(response));
     }

	public void register(Class<? extends AbstractRequest> piped, ServiceProvider handler) {
		registry.register(piped, handler);
	}
	
	public void register(Class<? extends AbstractRequest> piped, ServiceObserver handler) {
		registry.register(piped, handler);
    }

	public AbstractResponse process(AbstractRequest request) {
		throw new ShouldNotBeCalledException();
	}

	public void setCredentials(String credentials) {
		this.credentials  = credentials;
    }

}
